﻿namespace SLS.ExClassLib.WCFClient
{
    /*
    /// <summary>
    /// Implementation of the callback contract.
    /// </summary>
    public class WorkFlowCenterCallBackClient
    {
        #region =================SINGLETON=================
        /// <summary>
        /// Singleton
        /// </summary>
        public static readonly WorkFlowCenterCallBackClient Instance = new WorkFlowCenterCallBackClient();

        public Dictionary<string, object> MessageList;

        #endregion
        private WorkFlowCenterServiceClient m_WFClient;
        public WorkFlowCenterServiceClient WFClient
        {
            get { return m_WFClient; }
            set { m_WFClient = value; }
        }
        private InstanceContext instanceContext;
        private string m_Address;
        public string Address
        {
            get { return m_Address; }
            set { m_Address = value; }
        }
        public WorkFlowCenterCallBackClient()
        {
            MessageList = new Dictionary<string, object>();
            WorkFlowCenterCallBack chatServiceCallback = new WorkFlowCenterCallBack();
            chatServiceCallback.ClientNotified += ChatServiceCallback_ClientNotified;
            instanceContext = new InstanceContext(chatServiceCallback);
            WFClient = new WorkFlowCenterServiceClient(instanceContext, "TcpBinding");
            MessageEx msgRequest = new MessageEx();
            m_Address = "MA" + Guid.NewGuid().ToString();
            msgRequest.Address = m_Address;
            msgRequest.JobID = "OnAgentSubscribe";
            #region WorkQueue

            #endregion
            try
            {
                WFClient.WFService(msgRequest);
            }
            catch (Exception ex)
            {
                //throw;
            }
        }
        private void ChatServiceCallback_ClientNotified(object sender, ClientNotifiedEventArgs e)
        {
            ProcessWF2UIMessage(e.ThisMessage);
        }
      
        #region =================METHOD=================
        public void RegisterMessage(MessageEx TheMessage)
        {
            if (!WorkFlowCenterCallBackClient.Instance.MessageList.ContainsKey(TheMessage.MessageID))
            {
                WorkFlowCenterCallBackClient.Instance.MessageList.Add(TheMessage.MessageID, TheMessage);
            }
        }
        public void StartCenterWF(string Address)
        {
            DataAccessService.Instance.BaseMessage.Address = Address;
            MessageEx WFMsgRequest = new MessageEx(DataAccessService.Instance.BaseMessage);
            WFMsgRequest.JobType = "UI2WF";
            WFMsgRequest.JobID = "OnStartCenterWF";
            WFMsgRequest.JobContent = "CenterWorkFlow";
            SendWFMessage(WFMsgRequest);
        }
        public void SendWFMessage(MessageEx TheMessage)
        {
            try
            {
                //触发消息的界面传入
                //TheMessage.Address = Address;
                TheMessage.MessageID_Return = TheMessage.MessageID;
                WorkFlowCenterCallBackClient.Instance.RegisterMessage(TheMessage);
                MessageEx WFMessage = new MessageEx(TheMessage, false);
                if (TheMessage.JobID != "OnThisFail" && !TheMessage.JobID.StartsWith("OnList"))
                {
                    WFMessage.setReturn = null;

                }
                else
                {
                    if (TheMessage.setReturn != null)
                    {
                        WFMessage.setReturn = new DataSet();
                        foreach (DataTable dtTemp in TheMessage.setReturn.Tables)
                        {
                            if (dtTemp.TableName.Contains("QueryCond"))
                            {
                                WFMessage.setReturn = (DataSet)DataAccessService.Instance.ImportDataTable(WFMessage.setReturn, dtTemp);
                            }
                        }
                    }
                }
                WFMessage.setRequest = null;
                WFMessage.MessageID = TheMessage.MessageID;
                WorkFlowCenterCallBackClient.Instance.WFClient.WFService(WFMessage);
            }
            catch (Exception ex)
            {
                Tracer.Error("ClientWFService.SendWFMessage", ex);
            }
        }
        /// <summary>
        /// Event delegate ReplyReqJob
        /// </summary>
        public void ReplyReqJob(MessageEx ReqMessage)
        {
            try
            {
                string JobType = "Return";
                DataSet dsReturn = ReqMessage.setReturn;
                MessageEx WFMsgReply = new MessageEx(ReqMessage);
                if (ReqMessage.JobType == "WF2UI")
                {
                    if (JobType == "Return")
                    {
                        WFMsgReply.JobType = "UI2WF";
                    }
                }
                WFMsgReply.setRequest = null;
                WFMsgReply.setReturn = null;
                if (dsReturn != null)
                {
                    ReqMessage.setReturn = new DataSet();
                    foreach (DataTable dtTmp in dsReturn.Tables)
                    {
                        ReqMessage.setReturn = (DataSet)DataAccessService.Instance.ImportDataTable(ReqMessage.setReturn, dtTmp);
                    }
                }
                WFMsgReply.MessageID_Req = ReqMessage.MessageID;
                string JobID_Req = ReqMessage.JobID_Req;
                //if (FormType != "QueryCondition")
                {
                    if (JobID_Req == "OnSelectedRecordEdit")
                    {
                        WFMsgReply.JobID = "OnSingleEnd";
                    }
                }

                SendWFMessage(WFMsgReply);
            }
            catch (Exception ex)
            {
                Tracer.Error("ClientWFService.ReplyReqJob", ex);

            }
        }

        public void ProcessWF2UIMessage(MessageEx This_Message)
        {
            RegisterMessage(This_Message);
            string MessageID_Req = This_Message.MessageID_Req;
            MessageEx ReqMsg;
            if (MessageList.ContainsKey(MessageID_Req))
            {
                ReqMsg = (MessageEx)MessageList[MessageID_Req];
                This_Message.setRequest = new DataSet();
                This_Message.JobID_Req = ReqMsg.JobID;
                //查询结果
                if (ReqMsg.setReturn != null)
                {
                    foreach (DataTable dtTmp in ReqMsg.setReturn.Tables)
                    {
                        This_Message.setRequest = (DataSet)DataAccessService.Instance
                            .ImportDataTable(This_Message.setRequest, dtTmp);
                    }
                }
                //依据何种条件，得到这个结果
                if (ReqMsg.setRequest != null)
                {
                    foreach (DataTable dtTmp in ReqMsg.setRequest.Tables)
                    {
                        if (!This_Message.setRequest.Tables.Contains(dtTmp.TableName))
                        {
                            This_Message.setRequest = (DataSet)DataAccessService.Instance
                                .ImportDataTable(This_Message.setRequest, dtTmp);
                        }
                    }
                }
            }
            try
            {
                string JobID = This_Message.JobID;
                string JobType = This_Message.JobType;

                string JobContent = This_Message.JobContent;
                string Request = This_Message.Address;

                ZoomDocument doc = null;
                doc = (ZoomDocument)DocumentFactory.Instance.FindDocument(Request);
                if (doc != null)
                {
                    doc.ProcessWFMessage(This_Message);
                }
                return;
            }
            catch (Exception ex)
            {
                Tracer.Error("ClientWFService.ProcessWF2UIMessage", ex);
            }
        }
        #endregion
    }
    [CallbackBehavior(
    ConcurrencyMode = ConcurrencyMode.Multiple,
    UseSynchronizationContext = false)]
    public class WorkFlowCenterCallBack : WorkFlowCenterServiceCallBack
    {
        public event ClientNotifiedEventHandler ClientNotified;
        public SynchronizationContext _uiSyncContext = null;
        public WorkQueue work;
        public delegate void SafeWinFormsThreadDelegate(MessageEx msg);
        public WorkFlowCenterCallBack()
        {
            _uiSyncContext = SynchronizationContext.Current;
            work = new WorkQueue();
            work.ConcurrentLimit = 1;
            ((WorkThreadPool)work.WorkerPool).MaxThreads = 1;
            work.AllWorkCompleted += new EventHandler(work_AllWorkCompleted);
            work.WorkerException += new ResourceExceptionEventHandler(work_WorkerException);
            work.ChangedWorkItemState += new ChangedWorkItemStateEventHandler(work_ChangedWorkItemState);
        }
        private void BuildWorkQueue(MessageEx This_Message)
        {
            ExWorkItem ThisWorkItem =
                new ExWorkItem(This_Message);
            work.Add(ThisWorkItem);
        }
        private void work_ChangedWorkItemState(object sender, ChangedWorkItemStateEventArgs e)
        {
            SafeWinFormsThreadDelegate m_WF2UI =
                new SafeWinFormsThreadDelegate(WorkFlowCenterCallBackClient.Instance.ProcessWF2UIMessage);
            lock (this)
            {
                ExWorkItem exWinWI = (ExWorkItem)e.WorkItem;
                MessageEx msg = exWinWI.ThisMessage;
                WorkItemState state = exWinWI.State;
                if (state == WorkItemState.Completed)
                {
                    //this.Dispatcher.BeginInvoke(m_WF2UI, msg);
                    if (ClientNotified != null)
                    {
                        //ClientNotified(this, new ClientNotifiedEventArgs(msg));
                        Dispatcher.CurrentDispatcher.BeginInvoke(m_WF2UI, msg);
                    }
                }
            }
        }
        private void work_AllWorkCompleted(object sender, EventArgs e)
        {
            /*
            if (this.Dispatcher.CheckAccess())
            {
                this.Dispatcher.BeginInvoke(new EventHandler(work_AllWorkCompleted), new object[] { sender, e });
            }
            else
            {
                Cursor = Cursors.Arrow;
            }
            /

        }
 
        private void work_WorkerException(object sender, ResourceExceptionEventArgs ex)
        {
            //throw;
        }
        /// <summary> 
        /// Notifies the client of the message by raising an event. 
        /// </summary> 
        /// <param name="message">Message from the server.</param>
        [CLSCompliantAttribute(false)]
        public void NotifyWFClient(MessageEx msgRequest)
        {
            string AgentID = msgRequest.AgentID;
            SendOrPostCallback callback =
                delegate(object state)
                { this.BuildWorkQueue(msgRequest); };
            _uiSyncContext.Post(callback, AgentID);
        }
    }
    public delegate void ClientNotifiedEventHandler(object sender, ClientNotifiedEventArgs e);

    /// <summary> 
    /// Custom event arguments. 
    /// </summary> 
    public class ClientNotifiedEventArgs : EventArgs
    {
        private readonly MessageEx thisMessage;
        /// <summary> 
        /// Constructor. 
        /// </summary> 
        /// <param name="message">Message from server.</param>
        public ClientNotifiedEventArgs(MessageEx msgRequest)
        {
            this.thisMessage = msgRequest;
        }
        /// <summary>
        /// Gets the message.
        /// </summary> 
        public MessageEx ThisMessage
        {
            get
            {
                return thisMessage;
            }
        
    }}*/

}
